﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Gmei.MdiDemo
{
    public partial class GMText : UserControl
    {        
        Image _leftImage;
        Image _rightImage;

        bool _leftImageCature;
        bool _rightImageCature;

        EventHandler _leftImageClick;
        EventHandler _rightImageClick;
        EventHandler _keyEnter;

        private int ImageLeftMargin
        { get { return 6; } }

        private int ImageRightMargin
        { get { return 4; } }

        private int TxtBoxLeftMargin
        { get { return 4; } }

        private Rectangle LeftImageRect
        {
            get
            {
                if (_leftImage == null)
                    return Rectangle.Empty;

                int x = ImageLeftMargin;
                int y = (base.Height - _leftImage.Height) / 2;
                return new Rectangle(new Point(x, y), _leftImage.Size);
            }
        }

        private Rectangle RightImageRect
        {
            get
            {
                if (_rightImage == null)
                    return Rectangle.Empty;

                int x = base.Width - ImageRightMargin - _rightImage.Size.Width;
                int y = (base.Height - _rightImage.Size.Height) / 2;
                return new Rectangle(new Point(x, y), _rightImage.Size);
            }
        }

        public GMText()
        {
            InitializeComponent();
            SetStyle(ControlStyles.ResizeRedraw
                | ControlStyles.OptimizedDoubleBuffer
                | ControlStyles.UserPaint
                | ControlStyles.SupportsTransparentBackColor
                | ControlStyles.AllPaintingInWmPaint, true);
            UpdateStyles();
        }

        public override string Text
        {
            get
            {                
                return txtBox.Text;
            }
            set
            {                
                txtBox.Text = value;
            }
        }

        public Image LeftImage
        {
            get
            {
                return _leftImage;
            }
            set
            {
                _leftImage = value;
                RePositionTxtBox();
                Invalidate();
            }
        }

        public Image RightImage
        {
            get
            {
                return _rightImage;
            }
            set
            {
                _rightImage = value;
                RePositionTxtBox();
                Invalidate();
            }
        }

        public event EventHandler LeftImageClick
        {
            add { _leftImageClick = value; }
            remove { _leftImageClick = null; }
        }

        public event EventHandler RightImageClick
        {
            add { _rightImageClick = value; }
            remove { _rightImageClick = null; }
        }

        public event EventHandler TextKeyEnter
        {
            add { _keyEnter = value; }
            remove { _keyEnter = null; }
        }

        private void RePositionTxtBox()
        {
            txtBox.Anchor = AnchorStyles.None;
            int x;
            if (_leftImage != null)
                x = LeftImageRect.Right + TxtBoxLeftMargin;
            else
                x = TxtBoxLeftMargin;
            int width;
            if (_rightImage != null)
                width = RightImageRect.Left - TxtBoxLeftMargin - x;
            else
                width = base.Width - TxtBoxLeftMargin - x;
            int y = (base.Height - txtBox.Height) / 2;

            txtBox.Location = new Point(x, y);
            txtBox.Width = width;
            txtBox.Anchor = AnchorStyles.Left | AnchorStyles.Right;
        }

        private GraphicsPath CreateRoundedRect(Rectangle rect, int radius)
        {
            GraphicsPath path = new GraphicsPath();

            rect.Width--;
            rect.Height--;
   
            Rectangle rectTopLeft = new Rectangle(rect.X, rect.Y, radius, radius);
            Rectangle rectTopRight = new Rectangle(rect.Right - radius, rect.Y, radius, radius);
            Rectangle rectBottomLeft = new Rectangle(rect.X, rect.Bottom - radius, radius, radius);
            Rectangle rectBottomRight = new Rectangle(rect.Right - radius, rect.Bottom - radius, radius, radius);

            path.AddArc(rectTopLeft, 180, 90);
            path.AddArc(rectTopRight, 270, 90);
            path.AddArc(rectBottomRight, 0, 90);
            path.AddArc(rectBottomLeft, 90, 90);

            path.CloseFigure();
            return path;
        }

        private void DrawBorder(Graphics g)
        {
            Color c1 = Color.FromArgb(165, 165, 165);
            Color c2 = Color.FromArgb(231, 231, 231);
            
            SmoothingMode old = g.SmoothingMode;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            Rectangle rect = ClientRectangle;
            rect.Inflate(-2, -2);
            g.FillRectangle(Brushes.White,rect);
            rect.Inflate(2, 2);

            using (GraphicsPath path = CreateRoundedRect(rect, 4))
            {
                using (Pen p1 = new Pen(c1))
                {
                    g.DrawPath(p1, path);
                }
            }

            rect.Inflate(-1, -1);
            using (GraphicsPath path = CreateRoundedRect(rect, 4))
            {
                using (Pen p2 = new Pen(c2))
                {
                    g.DrawPath(p2, path);
                }
            }

            Point p4 = new Point(rect.X + 1, rect.Bottom - 1);
            Point p5 = new Point(rect.Right - 1, rect.Bottom - 1);
            Point p6 = new Point(rect.Right - 1, rect.Y + 1);
            using (Pen pen2 = new Pen(Color.FromArgb(120, 255, 255, 255)))
            {
                g.DrawLines(pen2, new Point[] { p4, p5, p6 });
            }

            g.SmoothingMode = old;
        }

        private void DrawLeftImage(Graphics g)
        {
            if (_leftImage == null)
                return;
            
            g.DrawImage(_leftImage, LeftImageRect);
        }

        private void DrawRightImage(Graphics g)
        {
            if (_rightImage == null)
                return;
            g.DrawImage(_rightImage, RightImageRect);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            DrawBorder(e.Graphics);
            DrawLeftImage(e.Graphics);
            DrawRightImage(e.Graphics);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            _leftImageCature = false;
            _rightImageCature = false;
            if (LeftImageRect.Contains(e.Location))
            {
                _leftImageCature = true;
                return;
            }
            if (RightImageRect.Contains(e.Location))
                _rightImageCature = true;
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            if (LeftImageRect.Contains(e.Location) && _leftImageCature)
            {
                if (_leftImageClick != null)
                    _leftImageClick(this, EventArgs.Empty);
            }
            else if (RightImageRect.Contains(e.Location) && _rightImageCature)
            {
                if (_rightImageClick != null)
                    _rightImageClick(this, EventArgs.Empty);
            }
            _leftImageCature = false;
            _rightImageCature = false;
        }

        private void txtBox_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (_keyEnter != null)
                    _keyEnter(this, EventArgs.Empty);
            }
        }
    }
}
